package reflectdemo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//反射的优缺点
/*
* 优点
* 1.对于任何一个类 都能够知道这个类的所有属性和方法；对于任意一个兑现，都能够调用他的任意一个方法
* 2.增强许多的灵活性和扩展性 降低耦合性 提高自适应能力
* 缺点
* 1. 使用反社会有效率问题 会导致程序效率降低
* 2.反射技术绕过了源代码技术 因而会带来维护问题
* */

public class ReflectDmo  {
    //通过反射 实例化对象
    public static void reflectNewInstance() {
        Class<?> c1;
        try{
            c1 = Class.forName("reflectdemo.Student");
            Student student = (Student)c1.newInstance();
            System.out.println(student);
        }catch(ClassNotFoundException e){
            throw new RuntimeException(e);
        }catch (InstantiationException e){
            throw new RuntimeException(e);
        }catch(IllegalAccessException e){
            throw new RuntimeException(e);
        }
    }
    //反射私有的构造方法  屏蔽内容为获得共有的构造方法
    public static void reflectPrivateConstructor(){
        Class<?> c1;
        try{
            c1 = Class.forName("reflectdemo.Student");
            Constructor<Student> con =
                    (Constructor)c1.getDeclaredConstructor(String.class,int.class);
            con.setAccessible(true);//设置了一个保险 相当于问你你确定吗
            Student student = con.newInstance("zhangsan",18);
            System.out.println(student);
        }catch(ClassNotFoundException e){
            throw new RuntimeException(e);
        }catch (NoSuchMethodException e){
            throw new RuntimeException(e);
        }catch(InvocationTargetException e){
            throw new RuntimeException(e);
        }catch (InstantiationException e){
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }
    //反射私有属性
    public static void relectPrivateField(){
        Class<?> c1;
        try{
            c1 = Class.forName("reflectdemo.Student");
            Field field = c1.getDeclaredField("name");
            field.setAccessible(true);
            Student student = (Student)c1.newInstance();
            field.set(student,"wangwu");
            System.out.println(student);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
    //反射私有方法
    public static void refelctPrivateMethod(){
        Class<?> c1;
        try {
            c1 = Class.forName("reflectdemo.Student");
            Method method = c1.getDeclaredMethod("function",String.class);
            method.setAccessible(true);
            Student student = (Student)c1.newInstance();
            method.invoke(student,"我是一个参数");

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args){
        //reflectNewInstance();
        //reflectPrivateConstructor();
        //relectPrivateField();//Student{name='wangwu', age=18}
        refelctPrivateMethod(); //我是一个参数
    }

}
